package com.epam.task.xml.parsers;

import com.epam.task.xml.classes.Analog;
import com.epam.task.xml.classes.Release;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.List;

public class SAXAnalyzer extends DefaultHandler {
    public static final Logger LOGGER = LoggerFactory.getLogger(SAXAnalyzer.class);
    private StringBuffer accumulator = new StringBuffer();
    private String name;
    private String factory;
    private String group;
    private String uid;
    private List<Analog> analogs;
    private Release release;

    public SAXAnalyzer() {
    }

    public void startDocument() throws SAXException {
        LOGGER.info("SAX parsing started...");
    }

    public void endDocument() throws SAXException {
        LOGGER.info("SAX parsing end.");
    }

    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {
        accumulator.setLength(0);
        if (qName.equals("medicine")) {
            uid = attributes.getValue("uid");
            group = attributes.getValue("group");
        }
    }

    public void characters(char[] buffer, int start, int length) {
        accumulator.append(buffer, start, length);
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (qName.equals("name")) {
            name = accumulator.toString().trim();
        } else if (qName.equals("factory")) {
            factory = accumulator.toString().trim();
        } else if (qName.equals("analog")) {
            Analog analog = new Analog(accumulator.toString().trim());
            for (int i = 0; i < analogs.size(); i++) {
                analogs.add(i, analog);
            }
        } else if (qName.equals("release")) {
            Release release = new Release(accumulator.toString());
        } else if (qName.equals("medicine")) {
            LOGGER.info("Medicine of group '" + group + "' " + name
                    + ((uid != null) ? " (uid=" + uid + ")" : "")
                    + "- factory: " + factory + ", analogs: " + analogs.toString()
                    + ", release: " + release.toString());
        }
    }

    public void warning(SAXParseException exception) {
        LOGGER.warn("WARNING: line " + exception.getLineNumber() + ": "
                + exception.getMessage());
    }

    public void error(SAXParseException exception) {
        LOGGER.error("ERROR: line " + exception.getLineNumber() + ": "
                + exception.getMessage());
    }

    public void fatalError(SAXParseException exception) throws SAXException {
        LOGGER.error("FATAL: line " + exception.getLineNumber() + ": "
                + exception.getMessage());
        throw (exception);
    }

}

